# import sys
# sys.path.append("..")
# sys.path.append("platform_h")

from simulation_onequeue import MicroserviceSystem
from multiprocessing import Pool
# from concurrent.futures import ThreadPoolExecutor
import pickle
import datetime
from util import *



class Parameter():
    def __init__(self):
        self.lamda_norm = 0.0001   #
        self.lamda_error = 0.01       #
        self.lamda_com = 8
        self.lamda_out = 1           #
        self.num_server = 15         #
        self.time_deadline = 2

def load_default_para():
    parameter_t=Parameter()
    return parameter_t

def run_once_sim(parameters):

    start_record_time=100
    ms_system=MicroserviceSystem(parameters.lamda_norm, parameters.lamda_error, parameters.lamda_com, parameters.lamda_out,
                                   parameters.num_server, parameters.time_deadline, start_record_time)
    one_cycle=1/parameters.lamda_norm+1/parameters.lamda_error
    ms_system.run(max(one_cycle*10,1000))
    _,sim_prob_time_error=ms_system.get_sim_reliability()
    print(f"complete sim:{parameters.num_server}_{parameters.lamda_out}_{parameters.lamda_norm}_{parameters.lamda_error}")
    return parameters, sim_prob_time_error

def run_once_math(parameters):
    start_record_time = 100
    ms_system = MicroserviceSystem(parameters.lamda_norm, parameters.lamda_error, parameters.lamda_com, parameters.lamda_out,
                                   parameters.num_server, parameters.time_deadline, start_record_time)
    _, math_prob_time_error = ms_system.get_math_reliability()
    print(f"complete math:{parameters.num_server}_{parameters.lamda_out}_{parameters.lamda_norm}_{parameters.lamda_error}")
    return parameters, math_prob_time_error


def threading_pool_dealing_only_math(task_args_list):
    global parrallel_num
    math_res=[]
    pool=Pool(parrallel_num)
    for parameter_t in task_args_list:
        res = pool.apply_async(run_once_math, args=(parameter_t,))
        math_res.append(res)
    return math_res



def optimize_mesh_one_vs_one(out_file_name,attr1, attr2,specific_list1,specific_list2):
    x_list = []
    y_list = []
    z_list=[]
    task_args_list = []
    for value1 in specific_list1:
        for value2 in specific_list2:
            parameter_t = load_default_para()
            setattr(parameter_t, attr1, value1)
            setattr(parameter_t, attr2, value2)
            task_args_list.append(parameter_t)
            math_res=threading_pool_dealing_only_math(task_args_list)
            
    for res in math_res:
        parameter_tt, value = res.get()
        x_list.append(getattr(parameter_tt, attr1))
        y_list.append(getattr(parameter_tt, attr2))
        z_list.append(value)

    with open(f"{get_output_absolute_path()}{out_file_name}", 'wb') as f:
        pickle.dump((x_list,y_list,z_list), f)
    return





global parrallel_num
parrallel_num=10

if __name__ == '__main__':
    para_t=Parameter()
    version=f"v1.0-{para_t.lamda_norm}-{para_t.lamda_error}-{para_t.lamda_com}-{para_t.lamda_out}-{para_t.num_server}-{para_t.time_deadline}"
    # 记录代码开始时间
    now_time = datetime.datetime.now()
    formatted_time = now_time.strftime('%m_%d_%H_%M_%S')

    num_server=[i for i in range(10,21)]
    lamda_out=[i for i in range(1,11)]
    lamda_norm=[i*0.0001 for i in range(1,11)]
    lamda_error=[i*0.01 for i in range(1,11)]

    #num_server vs lamda_out
    attr1="num_server"
    attr2="lamda_out"
    out_file_name = f"Exp_optimize_mesh_{attr1}_vs_{attr2}_{version}_{formatted_time}.data"
    optimize_mesh_one_vs_one(out_file_name,attr1,attr2,num_server, lamda_out)

    #lamda_norm vs lamda_error
    attr1="lamda_norm"
    attr2="lamda_error"
    out_file_name = f"Exp_optimize_mesh_{attr1}_vs_{attr2}_{version}_{formatted_time}.data"
    optimize_mesh_one_vs_one(out_file_name,attr1,attr2,lamda_norm, lamda_error)
    
    #num_server vs lamda_norm
    attr1="num_server"
    attr2="lamda_norm"
    out_file_name = f"Exp_optimize_mesh_{attr1}_vs_{attr2}_{version}_{formatted_time}.data"
    optimize_mesh_one_vs_one(out_file_name,attr1,attr2,num_server, lamda_norm)

    # lamda_out vs lamda_error
    attr1="lamda_out"
    attr2="lamda_error"
    out_file_name = f"Exp_optimize_mesh_{attr1}_vs_{attr2}_{version}_{formatted_time}.data"
    optimize_mesh_one_vs_one(out_file_name,attr1,attr2,lamda_out, lamda_error )
    
    
    
    
    


    

